package com.simons.common.utils.file.office;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import com.simons.common.utils.BeanTransfer;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public abstract class AbstractExcel {

	/**
	    * 读取 office excel
	    * @throws IOException
	    * @throws FileNotFoundException */
	public abstract <T> List<T> read(File file, String[] fieldNames, Class<T> calss) throws Exception;
	
	protected <T> List<T> read(Workbook xwb, int sheetAt, String[] fieldNames, Class<T> clazz) throws InstantiationException, IllegalAccessException{
		List<T> list = new LinkedList<T>();
		// 读取第一章表格内容
		Sheet sheet = xwb.getSheetAt(sheetAt);
		
        Iterator<Row> rowIterator = sheet.iterator();
        while (rowIterator.hasNext()) {
        	Row row = rowIterator.next();
        	Object value = null;
            if (row == null) {
            	log.debug("该row为空或则为标题");
                continue;
            }

//            List<Object> linked = new LinkedList<Object>();
            Map<String, Object> cellMap = new HashMap<String,Object>();
            T cellObj = null;
            for (int j = 0; j <= row.getLastCellNum(); j++) {
            	Cell cell = row.getCell(j);
                if (cell == null) {
                	if(j < row.getLastCellNum()){
                		log.debug("该cell为空");
                		value = "";
                		cellMap.put(fieldNames[j], value);
                	}
                	
                	continue;
                }

                switch (cell.getCellTypeEnum()) {
                case STRING:
                    value = cell.getStringCellValue();

                    break;

                case NUMERIC:
                    if (HSSFDateUtil.isCellDateFormatted(cell)) {  //判断日期类型
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
                        value = sdf.format(cell.getDateCellValue());
                    } else {  //否
                        value = new DecimalFormat("#.######").format(cell.getNumericCellValue());
                    }
                    break;

                case BOOLEAN:
                    value = cell.getBooleanCellValue();

                    break;

                case BLANK:
                    value = "";

                    break;

                default:
                    value = cell.toString();
                }

                if ((value == null) || "".equals(value)) {
                	value="";
                }

                cellMap.put(fieldNames[j], value);
                cellObj = BeanTransfer.mapToBean(cellMap, clazz);
            }

            list.add(cellObj);
        }
        return list;
	}
	
	/**
	    * 读取 office excel
	    * @throws IOException
	    * @throws FileNotFoundException */
	public abstract <T> List<T> read(File file, int sheetAt, String[] fieldNames, Class<T> calss)  throws Exception;
	
	public abstract int getNumberOfSheets(File file) throws Exception;
	
	public abstract int getSheetBySheetName(File file,String SheetName) throws Exception;
	
	public abstract int getSheetBySheetName(InputStream input, String SheetName) throws Exception;
	
	public abstract <T> void write(OutputStream out,String sheetName,String[] fieldNames, String[] heards,Collection<T> dataList) throws Exception;

	public abstract <T> Workbook getSimpleWorkBook();
	
	public abstract <T> SXSSFWorkbook writeToWorkBook(Workbook workbook, String sheetName, String[] fieldNames, String[] heards,Collection<T> dataList) throws Exception;

	public abstract <T> void writeByEnum(OutputStream out,String sheetName,String[] fieldNames, String[] heards,Collection<T> dataList, Map<String, Map<String, String>> enumMap) throws Exception;

	public abstract <T> List<T> read(InputStream input, int sheetAt, String[] fieldNames, Class<T> calzz) throws Exception;
}
